package com.beantools.file;

import com.beantools.constants.MainASCCode;
import com.beantools.constants.SingleChar;
import com.beantools.util.ArrayUtil;
import com.beantools.util.StringUtil;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;

import static com.beantools.constants.FrameConstant.JAVA_FILE_SUFFIX;
import static com.beantools.constants.FrameConstant.ROOT_PATH;
import static com.beantools.constants.RegexExpress.FILTER_JAVA_REG;
import static com.beantools.constants.SingleChar.EN_POINT;
import static com.beantools.constants.SingleChar.FORWARD_LEAN;
import static com.beantools.constants.SingleChar.INVERSE_LEAN;
import static com.beantools.util.StringUtil.isBlank;
import static com.beantools.util.StringUtil.isNotBlank;

/**
 * 这是加载外部项目的根目录下的所有java文件
 *
 * @author baoya
 * @version 1.1.0
 * @since 1.1.0
 */

public class LoadFiles extends AbstractFile {

    @Override
    public boolean exportJson(File file) throws IOException {
        return false;
    }

    /**
     * 这是加载外部项目下的所有目录，并装载到容器中
     */
    private static Set<String> fileSets = new LinkedHashSet<>();

    /**
     * 获取装载外部文件的容器
     *
     * @return fileSets 装载外部文件的容器
     */
    public static Set<String> getFileNames() {
        File file = initFile();
        loadFiles(file, JAVA_FILE_SUFFIX, EN_POINT);
        return fileSets;
    }

    /**
     * 加载jar包之外的项目文件，便于筛选调用者传递的文件。
     * <p>
     * 如果文件夹<code>dir</code>为空，则会抛出异常。
     *
     * @param dir 文件夹或者文件
     */
    private static void loadFiles(File dir) {
        loadFiles(dir, JAVA_FILE_SUFFIX, EN_POINT);
    }

    /**
     * 加载jar包之外的项目文件，便于筛选调用者传递的文件。
     * <p>
     * 如果文件夹<code>dir</code>为空，则会抛出异常。
     * <p>
     * 如果文件的后缀名<code>fileSuffix</code>为空，但<code>filterCharacter</code>不为空，
     * 则会过滤出不包含<code>filterCharacter</code>这个字符的文件或文件夹
     * <p>
     * 如果文件的后缀名<code>fileSuffix</code>不为空，则会过滤出这个文件夹或文件
     *
     * @param dir             文件夹或者文件
     * @param fileSuffix      过滤文件的后缀名
     * @param filterCharacter 过滤文件的字符集，也就是文件不包含那些字符
     */
    private static void loadFiles(File dir, String fileSuffix, String filterCharacter) {
        if (dir == null) {
            throw new IllegalArgumentException("文件夹为空dir=" + dir);
        }
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                // 过滤文件，必须为文件且以.java结尾，或者是文件目录
                String fileName = file.getName();
                if (isNotBlank(fileSuffix) && isNotBlank(filterCharacter)) {
                    return ((file.isFile() && fileName.endsWith(fileSuffix)) || (file.isDirectory() && !fileName.contains(filterCharacter)));
                } else if (isBlank(fileSuffix)) {
                    return (file.isFile() || (file.isDirectory() && !fileName.contains(filterCharacter)));
                } else if (isBlank(filterCharacter)) {
                    return ((file.isFile() && fileName.endsWith(fileSuffix)) || file.isDirectory());
                } else {
                    return (file.isFile() || file.isDirectory());
                }
            }
        });
        if (ArrayUtil.isNoNullObject(files)) {
            for (File var : files) {
                if (var.isDirectory()) {
                    loadFiles(var, fileSuffix, filterCharacter);
                } else if (var.isFile()) {
                    String fileName = var.getName();
                    boolean isMatch = StringUtil.verifyRegex(fileName, FILTER_JAVA_REG);
                    if (isMatch) {
                        String absolutePath = var.getAbsolutePath();
                        absolutePath = absolutePath.replace(ROOT_PATH, SingleChar.NULL_OP);
                        absolutePath = absolutePath.replace(FORWARD_LEAN, SingleChar.EN_POINT);
                        if (absolutePath.charAt(0) == MainASCCode.ASC_POINT) {
                            absolutePath = absolutePath.substring(1);
                        }
                        fileSets.add(absolutePath);
                    }
                }
            }
        }
    }

    /**
     * 加载外部文件的初始化
     */
    private static File initFile() {
        String tmp = ROOT_PATH.replace(FORWARD_LEAN, INVERSE_LEAN);
        String var1 = "";
        if (isNotBlank(tmp)) {
            String[] vars = tmp.split(INVERSE_LEAN);
            for (int i = 0; i < 3; i++) {
                if (i == 2) {
                    var1 += vars[i];
                    break;
                }
                var1 += vars[i] + INVERSE_LEAN;
            }
        }
        return isNotBlank(var1) ? new File(var1) : null;
    }
}
